package com.smit.icast;

import java.util.List;

import android.app.ActivityManager;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.SystemClock;

import com.smit.adapter.DVBAdapter;
import com.smit.adapter.DVBDevice;
import com.smit.adapter.DVBDeviceManager;
import com.smit.common.AuthControl;
import com.smit.dvb.jni.DVB;
import com.smit.utils.LogUtil;

/**
 * ICastAppService
 */
public class ICastAppService extends Service implements Handler.Callback
{
    /** DVB初始化OK，这里做的是USB参数的初始化 */
    public static final int CAM_USB_INIT_OK = 1;
    /** DVB未初始化成功，没有找到设备或没权限 */
    public static final int CAM_USB_INIT_FAIL = 2;
    /** CAM USB插入 */
    public static final int CAM_USB_ATTACHED = 3;
    /** CAM USB拔出 */
    public static final int CAM_USB_DETACHED = 4;

    private static final String TAG = "ICastAppService";
    private static final String TCL_START_SMIT_DVB_ACTION = "com.smit.dvb.TCL_START_SMIT_DVB";
    private static final String ACTION_SCREEN_OFF = "android.intent.action.SCREEN_OFF";
    private static final String ACTION_SCREEN_ON = "android.intent.action.SCREEN_ON";
    private static final String ACTION_SHUTDOWN = "android.intent.action.ACTION_SHUTDOWN";
    /* 申请CAM USB访问权限的pending intent action名 */
    private static final String ACTION_USB_PERMISSION = "com.smit.icast.USB_PERMISSION";
    private static final int RESET_TIMEOUT_COUNT = 40;
    private ICastDevice icastDevice;
    private DVBDeviceManager deviceManager;
    private PendingIntent permissionIntent;
    private Handler msgHandler;
    private boolean bCamUsbAttached = false;
    private int requestStatus = 0; // 0:初始状态; 1:调用了requestPerssion 2: onReceive
                                   // 3:没有权限

    private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver()
    {
        public void onReceive(Context context, Intent intent)
        {
            String action = intent.getAction();
            LogUtil.trace(TAG, "onReceive~~~ " + action);
            /* 关机 */
            if (ACTION_SHUTDOWN.equals(action))
            {
                LogUtil.trace(TAG, "onReceive~~~ " + ACTION_SHUTDOWN);
            }
            /* 申请完使用CAM USB设备后，系统通知的消息 */
            if (ACTION_USB_PERMISSION.equals(action))
            {
                LogUtil.trace(TAG, "onReceive:" + intent.getAction());
                synchronized (this)
                {
                    UsbDevice device = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
                    requestStatus = 0;
                    if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false))
                    {
                        if (device != null)
                        {
                            if (icastDevice.getStatus() == DVBDevice.DVB_DEVICE_HAS_RESET)
                            {
                                initDvbJni(device);
                            }
                            else
                            {
                                icastDevice.reset();
                            }
                        }
                    }
                    else
                    { // 没有获取到权限，重新再次申请
                        if (isUsbConfirmActivityOnTop())
                        { //有弹出权限申请的框，说明正在申请权限（系统或者我们自己在申请）
                            LogUtil.debug(TAG, "Requesting USB Permission");
                        }
                        else
                        {
                            LogUtil.error(TAG, "permission is denied for device " + device);
                            requestStatus = 1;
                            icastDevice.requestPermission(device, permissionIntent);
                        }
                    }
                }
            }
        }
    };

    /**dongle检测线程*/
    private Thread detectThread;
    /**复位过程中dongle被拔出，出现不提示，这里加超时来解决*/
    private int resetTimeout;

    @Override
    public void onCreate()
    {
        super.onCreate();
        LogUtil.debug(TAG, "onCreate~~~~~");
        deviceManager = DVBAdapter.getInstance().getDVBDeviceManager();
        assert (deviceManager == null) : "DVBAdapter is not initialized and deviceManager is null";
        if (deviceManager != null)
        {
            icastDevice = (ICastDevice) deviceManager.getDVBDevice();
        }
        assert (icastDevice == null) : "deviceManager is not initialized and icastDevice is null";
        /* msg Handler */
        msgHandler = new Handler(this);
        /* 启动鉴权线程 */
        // authThread = new AuthThread();
        // authThread.start();

        /* usb 权限申请pending intent */
        permissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);

        /* 监听USB拔插和权限申请消息 */
        registerReceiver(mUsbReceiver, new IntentFilter(ACTION_USB_PERMISSION));
        registerReceiver(mUsbReceiver, new IntentFilter(ACTION_SCREEN_OFF));
        registerReceiver(mUsbReceiver, new IntentFilter(ACTION_SCREEN_ON));
        registerReceiver(mUsbReceiver, new IntentFilter(ACTION_SHUTDOWN));
        /* 检测cam usb */
        if (icastDevice != null && icastDevice.isConnected())
        {
            bCamUsbAttached = true;
            UsbDevice usbDevice = icastDevice.getCamUsbDevice();
            if (usbDevice != null)
            {
                if (icastDevice.hasPermission(usbDevice))
                {
                    icastDevice.reset();
                }
                else
                {
                    LogUtil.error(TAG, "no permission!");
                    if (isUsbConfirmActivityOnTop())
                    { //有弹出权限申请的框，说明正在申请权限（系统或者我们自己在申请）
                        LogUtil.debug(TAG, "Requesting USB Permission");
                    }
                    else
                    {
                        if (requestStatus != 1)
                        { // 如果不是我们自己在申请权限，需要自己去申请权限
                            LogUtil.error(TAG, "start to Request USB Permission");
                            requestStatus = 1;
                            icastDevice.requestPermission(usbDevice, permissionIntent);
                        }
                    }
                }
            }
        }
        /*
         * 开启usb监测timer task 之前放在前面，初始状态Attached false,然后检测后会发送一个Attahced true,
         * 然后进入初始化，这个时候上面的代码对dongle进行复位，中间会发现没有设备。
         */
        startDetect();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId)
    {
        LogUtil.debug(TAG, "onStartCommand~~~~~");
        return START_STICKY;
    }

    @Override
    public void onLowMemory()
    {
        LogUtil.error(TAG, "onLowMemory~~~~~~");
        super.onLowMemory();
    }

    @Override
    public IBinder onBind(Intent intent)
    {
        LogUtil.debug(TAG, "onBind~~~~~");
        return null;
    }

    @Override
    public void onDestroy()
    {
        LogUtil.debug(TAG, "onDestroy~~~~~");
        icastDevice.releaseDevice();
        unregisterReceiver(mUsbReceiver);
        super.onDestroy();
    }

    private void initDvbJni(UsbDevice device)
    {
        LogUtil.debug(TAG, "initDvbJni start>>>");
        DVB.getInstance().deviceStatusChanged((byte) DVBDevice.DVB_DEVICE_CONNECTED,
                icastDevice.getDeviceFd());
        deviceManager.handleDeviceCallbackMsg(DVBDevice.DVB_DEVICE_INIT_OK, 0);
        AuthControl.getInstance().setAuthWaitFlag(false);
        LogUtil.debug(TAG, "initDvbJni end<<<");
    }

    private boolean isUsbConfirmActivityOnTop()
    {
        LogUtil.debug(TAG, "isUsbConfirmActivityOnTop 001");
        String activityName = "com.android.systemui.usb.UsbConfirmActivity";
        ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        List<RunningTaskInfo> runningTasks = manager.getRunningTasks(1);
        RunningTaskInfo cinfo = runningTasks.get(0);
        ComponentName component = cinfo.topActivity;
        LogUtil.debug(TAG, "isUsbConfirmActivityOnTop 002");
        if (component != null)
        {
            return activityName.equals(component.getClassName());
        }
        else
        {
            return false;
        }
    }

    private void startDetect()
    {
        LogUtil.trace(TAG, "startDetect~~~");
        if (detectThread != null)
        {
            detectThread.interrupt();
            detectThread = null;
        }
        detectThread = new Thread("detectThread")
        {
            @Override
            public void run()
            {
                while (true)
                {
                    /* 有的平台出现这里为空，导致后面崩溃了 */
                    while (icastDevice == null) {
                        icastDevice = (ICastDevice) DVBAdapter.getInstance().getDVBDeviceManager().getDVBDevice();
                        SystemClock.sleep(100);
                    }

                    boolean bIsAttached = icastDevice.isConnected();
                    //LogUtil.trace(TAG, "bIsAttached:" + bIsAttached);
                    if (bCamUsbAttached != bIsAttached)
                    {
                        bCamUsbAttached = bIsAttached;
                        if (bCamUsbAttached == false)
                        {
                            msgHandler.sendEmptyMessageDelayed(CAM_USB_DETACHED, icastDevice.getDetachTimeOut());
                            if (icastDevice.getDetachTimeOut() > 0)
                            {
                                LogUtil.debug(TAG, "CAM_USB_DETACHED delay " + icastDevice.getDetachTimeOut());
                                DVB.getInstance().deviceStatusChanged((byte) DVBDevice.DVB_DEVICE_DISCONNECTED,
                                        icastDevice.getDeviceFd());
                                icastDevice.releaseDevice();
                            }
                        }
                        else
                        {
                            icastDevice.setDetachTimeOut(0);
                            msgHandler.removeCallbacksAndMessages(null);
                            msgHandler.sendEmptyMessage(CAM_USB_ATTACHED);
                        }
                    }
                    if (bIsAttached == false && icastDevice.getStatus() == DVBDevice.DVB_DEVICE_IS_RESETTING)
                    { // 加一个超时，避免出现reset过程中dongle被人拔出而无法提示
                        resetTimeout++;
                        if (resetTimeout > RESET_TIMEOUT_COUNT)
                        {
                            icastDevice.setStatus(DVBDevice.DVB_DEVICE_DISCONNECTED); // dongle被拔出
                            msgHandler.sendEmptyMessage(CAM_USB_DETACHED);
                        }
                    }
                    else
                    {
                        resetTimeout = 0;
                    }
                    SystemClock.sleep(200);
                }
            }
        };
        detectThread.start();
    }

    @Override
    public boolean handleMessage(Message msg)
    {
        switch (msg.what)
        {
            case CAM_USB_ATTACHED:
                LogUtil.debug(TAG, "handleMessage: CAM_USB_ATTACHED");
                icastDevice.setStatus(DVBDevice.DVB_DEVICE_HAS_RESET);
                deviceManager.handleDeviceCallbackMsg(DVBDevice.DVB_DEVICE_CONNECTED, 0);
                preInitCamUsb();
                break;
            case CAM_USB_DETACHED:
                if (icastDevice.getStatus() == DVBDevice.DVB_DEVICE_IS_RESETTING)
                {
                    LogUtil.error(TAG, "handleMessage: CAM_USB_DETACHED caused by reset!");
                }
                else
                {
                    LogUtil.debug(TAG, "handleMessage: CAM_USB_DETACHED");
                    deviceManager.handleDeviceCallbackMsg(DVBDevice.DVB_DEVICE_DISCONNECTED, 0);
                    /*
                     * 这里不用恢复到0，否则出现多次复位，具体情况是这样的：
                     * dongle自己复位，复位过程activity又onResume,
                     * 发现这个标志为0，然后有重新对dongle复位了。
                     */
                    // CamUsb.setResetStatus(0);
                }
                DVB.getInstance().deviceStatusChanged((byte) DVBDevice.DVB_DEVICE_DISCONNECTED,
                    icastDevice.getDeviceFd());
                icastDevice.releaseDevice();
                break;
            default:
                break;
        }
        return false;
    }

    /**
     * @Title: preInitCamUsb
     * @Description: 遍历 USB设备，找到CAM USB设备，用CamUsb类来保存变量 这个主要用来查找cam
     *               usb设备，初始化CamUsb，jni的参数
     * @return: void
     */
    private void preInitCamUsb()
    {
        LogUtil.debug(TAG, "preInitCamUsb~~~resetStatus=" + icastDevice.getStatus());
        UsbDevice device = icastDevice.getCamUsbDevice();
        if (device != null)
        {
            if (icastDevice.hasPermission(device))
            { // 如果已经有权限，直接进行初始化
                initDvbJni(device);
            }
            else
            { // 如果系统没有记录权限，需要重新申请，去掉AttachActivity关联要打开这里
                LogUtil.error(TAG, "preInitCamUsb~~~hasPermission is false!");
                icastDevice.requestPermission(device, permissionIntent);
            }
        }
        else
        {
            deviceManager.handleDeviceCallbackMsg(DVBDevice.DVB_DEVICE_INIT_FAIL, 0);
        }
        return;
    }
}
